package main

import (
	"framework/using/fiber/middleware"
	"framework/using/fiber/model"
	"net/http"
	"sync"

	"github.com/gofiber/fiber/v2"
)

var (
	store   = []model.User{}
	idSeq   = 1
	storeMu sync.Mutex
)

func main() {
	app := fiber.New()
	api := app.Group("/api")

	api.Post("/users", middleware.BindAndValidate[model.User](), func(c *fiber.Ctx) error {
		req, ok := middleware.GetBindData[model.User](c)
		if !ok {
			return c.Status(http.StatusBadRequest).JSON(fiber.Map{
				"msg": "Bind data failed",
			})
		}

		storeMu.Lock()
		defer storeMu.Unlock()
		req.ID = idSeq
		idSeq++
		store = append(store, req)
		return c.Status(http.StatusCreated).JSON(fiber.Map{
			"msg":  "Create user success",
			"user": req,
		})
	})

	api.Get("/users", func(c *fiber.Ctx) error {
		return c.JSON(fiber.Map{
			"data": store,
		})
	})

	api.Get("/users/:id", func(c *fiber.Ctx) error {
		id, _ := c.ParamsInt("id")
		for _, u := range store {
			if u.ID == id {
				return c.JSON(u)
			}
		}
		return c.Status(http.StatusNotFound).JSON(fiber.Map{
			"msg": "User not found",
		})
	})

	api.Delete("/users/:id", func(c *fiber.Ctx) error {
		id, _ := c.ParamsInt("id")
		storeMu.Lock()
		defer storeMu.Unlock()
		for i, u := range store {
			if u.ID == id {
				store = append(store[:i], store[i+1:]...)
				return c.Status(http.StatusOK).JSON(fiber.Map{
					"msg": "Delete user success",
				})
			}
		}
		return c.Status(http.StatusNotFound).JSON(fiber.Map{
			"msg": "User not found",
		})
	})

	app.Listen(":8080")
}
